package com.quanta.edaily.controller;

import com.alibaba.fastjson.JSONObject;
import com.quanta.edaily.bean.JsonResponse;
import com.quanta.edaily.mapper.FilesMapper;
import com.quanta.edaily.pojo.Files;
import com.quanta.edaily.utils.RanUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Objects;

@RestController
@RequestMapping("/files")
public class FilesController {

    @Resource
    private FilesMapper filesMapper;
    @Value("${files.upload.path}")
    private String fileUploadPath;
    @Value("${ip}")
    private String ip;
    @Value("${server.port}")
    private String port;

    @PostMapping("/upload")
    public JsonResponse upload(@RequestParam MultipartFile file) throws IOException {

        if(file.isEmpty()) return JsonResponse.paramError("文件为空");
        String originalFilename = file.getOriginalFilename();
        String type = StringUtils.getFilenameExtension(originalFilename);
        String uuid = RanUtils.genUUID()+"."+type;
        String md5 = DigestUtils.md5DigestAsHex(file.getInputStream());
        String url;

        File uploadFile = new File(fileUploadPath+uuid);
        File parentFile = uploadFile.getParentFile();
        if(!parentFile.exists()) parentFile.mkdirs();
        Files dbFile = filesMapper.getFileByMd5(md5);
        if(dbFile==null) {
            file.transferTo(uploadFile);
            url = "http://"+ip+":"+port+"/files/download/"+uuid;
        } else {
            url = dbFile.getUrl();
        }

        Files saveFile = new Files();
        saveFile.setName(StringUtils.getFilename(originalFilename));
        saveFile.setSize(file.getSize()/1024);
        saveFile.setType(type);
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        filesMapper.insert(saveFile);
        JSONObject data = new JSONObject();
        data.put("id",saveFile.getId());
        data.put("url",url);
        return JsonResponse.success("上传成功", data);
    }

    @GetMapping("/download/{uuid}")
    public void download(@PathVariable String uuid, HttpServletResponse response) throws IOException {

        File file = new File(fileUploadPath+uuid);
        if(!file.exists()) return;
        ServletOutputStream os = response.getOutputStream();
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis);
        // 新建字节数组，长度是文件的大小，比如文件 6kb, bis.available() = 1024 * 6
        byte[] bytes = new byte[bis.available()];

//        response.reset(); // 重置 response
        // 设置 response 的下载响应头
//        response.setContentType("application/octet-stream"); // 设置后直接下载
        // 注意，这里要设置文件名的编码，否则中文的文件名下载后不显示, inline: 支持预览, attachment: 直接下载
        response.setHeader("Content-disposition", "inline;filename=" + URLEncoder.encode(uuid, "UTF-8"));

        bis.read(bytes); // 从文件流读取字节到字节数组中
        os.write(bytes); // 写出字节数组到输出流
        os.flush(); // 刷新输出流
        bis.close();
        fis.close();
        os.close();
    }

    @PostMapping("/updateById")
    public JsonResponse uploadById(@RequestBody Files file) {

        if(Objects.equals(file.getName(), ""))
            return JsonResponse.paramError("名字为空");
        if(filesMapper.updateById(file)==1)
            return JsonResponse.success("更改成功");
        return JsonResponse.systemError("更改失败");
    }

    @PostMapping("/deleteById/{id}")
    public JsonResponse deleteById(@PathVariable Integer id) {
        if(filesMapper.deleteById(id)==1)
            return JsonResponse.success("删除成功");
        return JsonResponse.systemError("删除失败");
    }

    @GetMapping("/getFileById")
    public JsonResponse getFileById(@RequestParam Integer id) {
        Files file = filesMapper.getFileById(id);
        if(file==null) return JsonResponse.paramError("文件为空");
        return JsonResponse.success("查询成功",file);
    }

    @GetMapping("/getAllFiles")
    public JsonResponse getAllFiles() {
        return JsonResponse.success("查询成功",filesMapper.getAllFiles());
    }
}
